﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Windows.Forms;
using App.Controlador;
using App.Modelo;
using App.Modelo.Interfaces;
using App.Modelo.Menu;
using App.Seguridad.Vista.Menu;
using MenuItem = System.Windows.Forms.MenuItem;

namespace App.Seguridad.Vista.Comandos
{
    public class RefrescarItemEventArgs : EventArgs
    {
        public ToolStripMenuItem Control;
        public Modelo.Menu.MenuBoton Boton;
    }

    public  class DibujarMenu
    {
        private ResourceManager _resourceManager;
        private Modelo.Menu.MenuContenedor _model;

        public event EventHandler<RefrescarItemEventArgs> DibujarItem;

        private Dictionary<ToolStripItem, MenuBaseItem> _itemsIndex
            = new Dictionary<ToolStripItem, MenuBaseItem>();


        public event EventHandler<MenuControladorItemCreado> ItemCreado;

        /// <summary>
        /// El evento se lanza cuando se ejecuta un comando
        /// </summary>
        public event EventHandler<MenuEjecutarComandoEventArgs> ExecuteCommand;

        /// <summary>
        /// El control MenuStrip que se usará para cargar los items
        /// </summary>
        public MenuStrip Menu { get; set; }

        /// <summary>
        /// Retorna el manejador de recursos utilizado. Si no se establece retorna un manejador
        /// de este assembly
        /// ResourceManager se usa para encontrar las imagenes.
        /// </summary>
        public ResourceManager ResourceManager
        {
            get {
                return _resourceManager ??
                       (_resourceManager = new ResourceManager(typeof (App.Seguridad.Vista.Properties.Resources)));
            }
            set { _resourceManager = value; }
        }


        /// <summary>
        /// Obtiene o establece el modelo de items del menu actualizando el ControlMenu
        /// </summary>
        public Modelo.Menu.MenuContenedor Model
        {
            get { return _model; }
            set
            {
                _itemsIndex.Clear();
                _model = value;

                Menu.Items.Clear();

                if (_model != null)
                {
                    foreach (var item in _model.Items)
                        Menu.Items.Add(_add(item));
                    Refrescar();
                }
            }
        }


        private void activar_menu(ToolStrip menu)
        {
            foreach (ToolStripItem element in menu.Items)
            {
                if (element is ToolStripMenuItem)
                {
                    ToolStripMenuItem item = (ToolStripMenuItem) element;

                    this.activar_menu(item.DropDown);

                    if (_itemsIndex.ContainsKey(element))
                    {
                        Modelo.Menu.MenuBoton modelBoton = (Modelo.Menu.MenuBoton) _itemsIndex[element];
                        if (modelBoton.ComprobarPermiso)
                        {
                            if (DibujarItem!=null)
                                DibujarItem(this, new RefrescarItemEventArgs()
                                                      {
                                                          Boton = modelBoton,
                                                          Control = item
                                                      });
                        }
                    }
                }
            }
        }


        private ToolStripItem _add(MenuBaseItem item)
        {
            ToolStripItem ret = createItem(item);
            if (item is Modelo.Menu.MenuBoton
                && ((Modelo.Menu.MenuBoton) item).Items.Length > 0
                && ret is ToolStripMenuItem)
            {
                var dd = (ToolStripMenuItem) ret;

                foreach (var it in ((Modelo.Menu.MenuBoton) item).Items)
                    dd.DropDown.Items.Add(_add(it));
            }

            _itemsIndex[ret] = item;

            return ret;
        }

        private ToolStripItem createItem(MenuBaseItem item)
        {
            var assembly = Assembly.GetAssembly(typeof (ToolStripItem));

            var tipo = assembly.GetType("System.Windows.Forms.ToolStrip" + item.Type);

            var constructorInfo = tipo.GetConstructor(Type.EmptyTypes);

            if (constructorInfo != null)
            {
                var button = (ToolStripItem) constructorInfo.Invoke(null);

                if (!String.IsNullOrEmpty(item.Image)
                    && ResourceManager.GetObject(item.Image) is Image)
                    button.Image = (Image) ResourceManager.GetObject(item.Image);

                button.Text = item.Text;

                if (!String.IsNullOrEmpty(item.Command))
                    button.Click += new EventHandler(button_Click);



                if (null != ItemCreado)
                    ItemCreado(this, new MenuControladorItemCreado
                                         {
                                             Control = button, 
                                             Item = item
                                         });
                item.Control = button;

                return button;
            }
            return null;
        }

        private void button_Click(object sender, EventArgs e)
        {
            if (_itemsIndex.ContainsKey((ToolStripItem) sender))
            {
                MenuBaseItem item = _itemsIndex[(ToolStripItem) sender];

                if (ExecuteCommand != null)
                    ExecuteCommand(this, new MenuEjecutarComandoEventArgs {Item = item});
            }
        }


        /// <summary>
        /// Vuelve a aplicar la seguridad
        /// </summary>
        public void Refrescar()
        {
            activar_menu(Menu);
        }

    }

}
